/**
 * \file packet_tcp.c
 * \brief Packet TCP
 * \author Pierre Neumann / Julien Meutelet
 * \version 0.1
 * \date 20 decembre 2013
 *
 * Sert à Initialiser l'entête TCP et à l'afficher
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h> 
#include <netinet/tcp.h> 
#include <arpa/inet.h>

#include "packet_utils.h"
#include "packet_ip.h"
#include "packet_tcp.h"

const size_t TCP_HEADER_SIZE = sizeof(struct tcphdr); /*!< Taille de l'entête TCP */
const size_t TCP_PACKET_SIZE = sizeof(struct ip) + sizeof(struct tcphdr); /*!< Taille d'un paquet TCP */ 
const int TCP_PROTOCOL_NUMBER = 6; /*!< Numéro du protocole TCP */

/**
 * \fn init_tcp_header(char** packet, struct in_addr* destination, struct in_addr* source,int port,int ttl)
 * \brief Initialise un paquet TCP
 *
 * \param packet Chaine de caractère représentant le paquet TCP.
 * \param destination Pointeur vers la structure in_addr de la destination.
 * \param source Pointeur vers la structure in_addr de la source.
 * \param port Port sur lequel on souhaite envoyer le paquet.
 * \param ttl Entier utilisé pour initialiser le champ ttl de l'entête IP.
 * \return Rien.
 */
void init_tcp_header(char** packet, struct in_addr* destination, struct in_addr* source,int port,int ttl){
	// On alloue la taille d'un paquet TCP
	*packet = (char *) malloc(TCP_PACKET_SIZE);  

	// Initialisation de l'entête IP
	init_ip_header(packet,destination,source,TCP_HEADER_SIZE,TCP_PROTOCOL_NUMBER,ttl);

	// On complète les champs de l'entête TCP
	struct tcphdr * htcp; 
	htcp = (struct tcphdr *) (*packet + IP_HEADER_SIZE); 
	htcp->source = htons(5658); 
	htcp->dest = htons(port); 
	htcp->seq = random();
	htcp->ack_seq = 0;
	htcp->doff = 5;
    	htcp->fin=0;
    	htcp->syn=1;
    	htcp->rst=0;
    	htcp->psh=0;
    	htcp->ack=0;
    	htcp->urg=0;
	htcp->window = htons(65535);
	htcp->check = 0;
	htcp->urg_ptr = 0;
	// On calcule la checksum avec pseudo-header 
	htcp->check = checksum_with_pseudoheader(packet,TCP_HEADER_SIZE);
}

/**
 * \fn print_tcp_header(char** packet)
 * \brief Affiche l'entête TCP d'un paquet
 *
 * \param packet Chaine de caractère représentant le paquet TCP.
 * \return Rien.
 */
void print_tcp_header(char** packet){
	struct tcphdr *htcp = (struct tcphdr *) (*packet + IP_HEADER_SIZE);
	printf("------Entête TCP------\n");
	printf("Port source : %d\n",ntohs(htcp->source));
	printf("Port destination : %d\n",ntohs(htcp->dest));
	printf("Seq : %d\n",ntohl(htcp->seq));
	printf("Ack : %d\n",ntohl(htcp->ack_seq));
	printf("Fenêtre : %d\n",htcp->window);
	printf("Checksum : %d\n",htcp->check);
	printf("urg : %d\n",htcp->urg_ptr); 
}
